/**
 * 
 */
package org.dragonfire.util;

import java.math.BigDecimal;

import com.stevesoft.pat.Regex;

public class DMath {

	public static double round(double number, int decimalPlaces) {
		if (decimalPlaces < 0)
			decimalPlaces = 0;
		BigDecimal d = new BigDecimal(number);
		d = d.setScale(decimalPlaces, BigDecimal.ROUND_HALF_UP);
		return d.doubleValue();
	}

	/**
	 * This method is a workaround for the problem that while
	 * <code>Double.toString()</code> will write a number in scientific
	 * notation (using an "<code>E</code>" to represent <code>*10^</code>),
	 * <code>Double.parseDouble()</code> will not read the written String.<br />
	 * This method can parse a double value from a string, with support for
	 * scientific notation.
	 * 
	 * @param number
	 *            The number to parse in String format
	 * @return A double value representing the passed String
	 */
	public static double parseDouble(java.lang.String number) {
		Regex doub = new Regex("([-\\d\\.]+)([Ee][-\\d\\.])?");
		if (doub.search(number)) {
			double num = Double.parseDouble(doub.stringMatched(1));
			double exp = 0;
			if (doub.stringMatched(2) != null)
				exp = Double.parseDouble(doub.stringMatched(2));
			return num * java.lang.Math.pow(10, exp);
		}
		else
			throw new RuntimeException("Invalid double format '" + number + "'.");
	}

	/**
	 * Returns the fraction part of a floating-point number.
	 * 
	 * @param number
	 *            The number to retreive the fractional part from
	 * @return The fractional part of <code>number</code>
	 */
	public static double fPart(double number) {
		// simply subtract the integer part to leave the remainder
		return number - (int) number;
	}

	public static byte[] trimBin(int number, int bytes) {
		byte[] out = new byte[bytes];
		for (int i = 0; i < bytes; i++) {
			out[bytes - i - 1] = (byte) (number & 0xFF);
			number >>= 8;
		}
		return out;
	}

	public static String ordinal(int number) {
		switch (number) {
			case -1:
			case 1:
				return number + "st";
			case -2:
			case 2:
				return number + "nd";
			case -3:
			case 3:
				return number + "rd";
			default:
				return number + "th";
		}
	}

	public static boolean isInteger(String text) {
		try {
			new Integer(text);
			return true;
		} catch (NumberFormatException ne) {
			return false;
		}
	}

	public static String changeBase(String inNum, int inBase, int outBase) {
		int num = Integer.parseInt(inNum, inBase);
		return Integer.toString(num, outBase);
	}
}